package domain

import (
	"context"
	"time"

	"github.com/lab-online/internal/lab/constant"
	"github.com/lab-online/internal/lab/entity"
	"github.com/lab-online/internal/lab/interface/include"
	"github.com/lab-online/internal/shared/code"
	"github.com/lab-online/pkg/util"
)

type MQ interface {
	// ProduceExperiment 发布执行实验消息
	ProduceExperiment(entity.LabEntity) (entity.LabEntity, error)
}

type Domain struct {
	mq     MQ
	oss    OSS
	report include.ReportService
	class  include.ClassService
	course include.CourseService
}

type LabDomain interface {
	Mimo
}

type Mimo interface {
	MimoDecode(entity.LabEntity) (entity.LabEntity, error)
	MimoPlot(entity.LabEntity) (entity.LabEntity, error)

	CreateUploadURL(entity.LabEntity) (string, error)
}

type OSS interface {
	PresignedPutObjectURL(ctx context.Context, bucketName string, objectKey string, expire time.Duration) (string, error)
}

func New(
	mq MQ,
	oss OSS,
	rs include.ReportService,
	cs include.ClassService,
	course include.CourseService,
) LabDomain {
	return &Domain{mq, oss, rs, cs, course}
}

func handleStatusError(status, executing uint) error {
	switch {
	case util.BitMaskHas(status, code.StatusLocked):
		return constant.RESTErrIsLocked
	case util.BitMaskHas(status, code.StatusReviewing):
		return constant.RESTErrIsReviewing
	case util.BitMaskHas(status, executing):
		return constant.RESTErrIsExecuting
	}
	return nil
}
